

TOS      Saved during Task switching.
ENTRY    Jumped to during multitasking.
LINK     Points to next task in the circular queue
SP0      Empty parameter stack for this task.
RP0      Empty return stack for this task.
DP       Size of dictionary.  Next available location.
#OUT     Number of characters sent since last CR.
#LINE    Number of CR's sent since last page.
OFFSET   Added to all block references.
BASE     The current numeric base for number input output.
HLD      Points to a converted character during numeric output.
FILE     Allows printing of one file while editing another.
IN-FILE  Allows printing of one file while editing another.
PRINTING  indicates whether printing is enabled.
YDP      Size of headers.  Next available location.
EMIT     Sends a character to the output device.

SCR      Holds the screen number last listed or edited.
PRIOR    Points to the last vocabulary that was searched.
DPL      The decimal point location for number input.
WARNING  Checked by WARN for duplicate warnings.
R#       The cursor position during editing.
HLD      Points to a converted character during numeric output.
LAST     Points to the name of the most recently CREATEd word.
CSP      Used for compile time error checking.
CURRENT  New words are added to the CURRENT vocabulary.
#VOCS    The number of elements in the search order array.
CONTEXT  The array specifying the search order.

'TIB     Points to characters entered by user.
WIDTH    Number of characters to keep in name field.
VOC-LINK Points to the most recently defined vocabulary.
BLK      If non-zero, the block number we are interpreting.
>IN      Number of characters interpreted so far.
SPAN     Number of characters input by EXPECT.
#TIB     Used by WORD, when interpreting from the terminal.
END?     True if input stream exhausted, else false.

BL
BS
BELL     Names for BLank, BackSpace, and BELL
CAPS           If true, then convert names to upper case
FILL
   FILL the string starting at start-addr for count bytes
   with the character char.  Both BLANK and ERASE are
   special cases of FILL.

ERASE      Fill the string with zeros
BLANK      Fill the string with blanks
COUNT     Given the address on the stack, returns the address
   plus one and the byte at that address.  Useful for strings.
LENGTH    Given the address on the stack, returns the address
   plus two and the two byte contents of the address.
MOVE
   Move the specified bytes without overlapping.

>UPPER
   subroutine which converts character in AX to upper case.
UPC
   Convert a Char to upper Case
UPPER
   Take the string at the specified address and convert it to
   upper case.  It converts the string in place, so be sure to
   make a copy of the original if you need to use it later.
HERE      Return the address of the top of the dictionary
PAD       Floating Temporary Storage area.
-TRAILING   Return the address and length of the given string
   ignoring trailing blanks.

COMP   This performs a string compare.  If the two strings are
   equal, then COMPARE returns 0.  If the two strings differ,
   then COMPARE returns -1 or +1.  -1 is returned if string 1
   is less than string 2.  +1 is returned if string 1 is
   greater than string 2.  All comparisons are relative to
   ASCII order.
CAPS-COMP
   The code on this screen handles the case where case is not
   significant.  Each character is converted to upper case
   before the comparison is made.  Thus, lower case a and upper
   case A are considered identical.
COMPARE
   Performs a string compare. If CAPS is true, characters from
   both strings are converted to upper case before comparing.

OSF    Operating Sys call in progress flag.
FCDOS called by other assembler code to do INT 21 (DOS call).
  BP and SI are the critical FORTH registers.  Create is used
  here to force force lable into target dictionary. OSF is set
  during the DOS call, can be tested by interrupt routines
  which call non-reentrant DOS functions.
XFDOS : call INT 21 with most any reg combination used.
?CS: : leave FORTH CS on stack
@L : ( seg adr - n ) load word long
C@L : ( seg adr - byt) char load long

C!L : ( byt seg adr -) char store long
!L : ( n seg adr -- ) word store long

BDOS     Load up the registers and do a DOS system call.
   return the result placed in the A register on the
   stack.

(KEY?)
   Returns true if the user pressed a key, otherwise false.
(KEY)
   Pauses until a key is ready, and returns it on the stack.
(EMIT)   Sends the character to the terminal.

CMOVEL : ( sseg sptr dseg dptr cnt ) move char block long.
YSTART : if non-zero, ptr to start of headers after dictionary.
   Used to set DP in this case.
YSEG : SEG for header segment
MEMCHK : abort with memory error message if true
DOSVER : get DOS version number
SETYSEG : move headers after dictionary to their own segment.
  Reserves 100k space (DOS 2.x required).  Copies headers to
  the alloted space


Probably should have YALLOT also for completeness.  Wasn't
   needed very often.

KEY?  Usually set to (KEY?), to sense keyboard status.
KEY   Usually set to (KEY) to get a character from the user.
CR     Typically set to CRLF, above.
PR-STAT  Return printer status, if implemented, else TRUE
(PRINT)  The value of the DEFERRED word EMIT when you
   want to send a character to the printer.
(EMIT)  sends a character to both the console and the printer.

CRLF     Sends a carriage return line feed sequence.
TYPE   Display the given string on the terminal.
SPACE        Send a space to the terminal
SPACES       Send a set of spaces to the terminal
BACKSPACES   Send a set of Backspaces to the terminal.
BEEP         Ring the bell on the terminal

BS-IN
   If at beginning of line, beep, otherwise back up 1.
(DEL-IN)
   If at beginning of line, beep, otherwise back up and erase 1.
BACK-UP
   Wipe out the current line by overwriting it with spaces.
RES-IN
   Reset the system to a relatively clean state.
P-IN
   Toggle the printer on or off

CR-IN
   Finish input and remember the number of chars in SPAN
(CHAR)
   Process an ordinary character by appending it to the buffer.
CHAR  is usually (CHAR). Executed for most characters.
DEL-IN is usually (DEL-IN). Executed for delete characters.

CC   Points to current control character table.
CC-FORTH
   Handle each control character as a special case.  This
   generates an execution array which is indexed into by
   EXPECT to do the right thing when it receives a control
   character.

EXPECT
   Get a string from the terminal and place it in the buffer
   provided.  Performs a certain amount of line editing.
   Saves the number of characters input in the Variable SPAN.
   Processes control characters per the array pointed to by CC.

TIB     Leaves address of text input buffer.
QUERY   Get more input from the user and place it at TIB.

These variables are used by the BLOCK IO part of the system.
Unlike FIG Forth the buffers are managed in a true least
recently used scheme.  The are maintained in memory as an array
of 8 byte entries, whose format is defined at left.  Whenever
a BLOCK is referenced its pointer is moved to the head of the
array, so the most recently used buffer is first. Thus multiple
references are very fast.  Also we have eliminated the need for
a null at the end of each BLOCK buffer so that the size of a
buffer is now exactly 1024 bytes.
The format of entries in the buffer-pointer array is:
   0-1 is Block Number         2-3 is Pointer to File
   4-5 is Address of Buffer    6-7 is Update Flag
BUFFER#   Return the address the the nth buffer pointer.
>END      Return a pointer to just past the last buffer packet.
>UPDATE   Return a pointer to the update flag.

READ-BLOCK   performs physical read.
WRITE-BLOCK   performs physical write.
.FILE   (S adr -- )
  print filename in fcb at adr.
FILE?   (S -- ) print name of current file.
SWITCH   exchange in-file and file.

DOS  vocabulary for native file system interface words.
!FILES  sets both file pointers to the specified file.
DISK-ABORT   (S fcb a n -- )
  print error message and file name.
?DISK-ERROR  (S fcb n -- )
  report disk error.


CLR-FCB      Initialize the specified FCB.
SET-DMA      CP/M system call to set dma address
RECORD#      Pointer to the specified Ramdom Record
MAXREC#      Pointer to the largest record allowed
IN-RANGE     Makes sure that the Random Record is
   within Range.  Issues error message if it isn't.
REC-READ     Do a Random Access read
REC-WRITE    Do a Random Access write

SET-IO  common set-up for file reads and writes.

FILE-READ  read 1024 bytes from a file.

FILE-WRITE  write 1024 bytes to a file.

FILE-IO  set block read and writes to use files.


CREATE SOURCE-BUF 1026 ALLOT      SOURCE-BUF 1026 ERASE

: GET-BLOCK     (S BLK# -- )
                [ DOS ] MYBUFFER (SET-DMA)
                IN-FCB @ >R
                      R@ RECORD# !
                B/REC R@ BREC#   !
                      R> 33 BDOS ;

( .EXE file support                            12:19 04/22/86 )
XCKSUM  checksums a block of memory using word addition ( cnt
   must be even )
SUVEC  startup vector, for a long jump to HEX 100 to set up
   CS correctly.  Currently the .EXE header has CS set at
   0FFF0h which fakes out the loader to set CS to the same
   as the Program Sement Prefix.  This makes the long jump
   unnecessary, but we put it in so we could easily make
   the .EXE header more conventional.
SEXE  entry point specified by .EXE header.  Sets the seg part
   of SUVEC, moves FORTH headers up to seg after DS (YSEG),
   does long jump thru SUVEC to start system.
EHMT  empty .EXE header.  Entries 0Eh and 16h are SS and CS,
   set to -10h, somewhat questionable.  If they are changed,
   10h and 14h must be changed to compensate.


CAPACITY     The number of blocks in the current file
LATEST?   For increased performance we first check to see if the
   block we want is the very first one in the list.   If it is
   return the buffer address and false, and exit from the word
   that called us, namely ABSENT?.  Otherwise we return as
   though nothing had happened.
ABSENT?
   Search through the block/buffer list for a match.  If it is
   found, bring the block packet to the top of the list and
   return a false flag and the address of the buffer.  If the
   block is not found, return true, indicating it is absent,
   and the second parameter is garbage.

UPDATE   Mark the most recently used buffer as modified.
DISCARD  Mark the most recently used buffer as unread.
MISSING   Writes the least recently used buffer to disk if it
   was modified, and moves all of the buffer pointers down by
   one, making the first one available for the new block.  It
   then assigns the newly available buffer to the new block.
(BUFFER)  assigns a buffer to the specified block in the given
  file. No disk read is performed. Leaves the buffer address.
BUFFER  assigns a buffer to the specified block.
  No disk read is performed. Leaves the buffer address.
(BLOCK) Leaves the address of a buffer containing the given
  block in the given file. Reads the disk if necessary.
BLOCK   Leaves the address of a buffer containing the given
  block. Reads the disk if necessary.
IN-BLOCK  like BLOCK, but for the IN-FILE.
EMPTY-BUFFERS
   First wipe out the data in the buffers.  Next initialize the
   buffer pointers to point to the right addresses in memory
   and set all of the update flags to unmodified.
SAVE-BUFFERS
   Write back all of the updated buffers to disk, and mark them
   as unmodified.  Use this whenever you are worried about
   crashing or losing data.
FLUSH     Save and empties the buffers. Used for changing disks.
  The phrase " 0 BLOCK DROP " is a kludge for CP/M. Some
  systems do extra buffering in the BIOS, and you must access
  a new block to be sure the old one is actually written to disk
VIEW#  returns address of the view# field for this file.


FILE-SIZE    Return the size of the file in records.
DOS-ERR?     Returns true if a DOS error occurred.
OPEN-FILE
   Open the current file and tell user if you can't.
   Determine the size of the file and save it for error check.
DOS-FCB      The address where the DOS puts a parsed FCB
DEFAULT   Opens the default file per the execute line.  Move the
   already parsed file control block into FCB1, and open the
   file.  This does nothing if no file was given.
(LOAD)
   Load the screen number that is on the stack.  The input
   stream is diverted from the terminal to the disk.
LOAD    Interpret a screen as if it were type in .

DIGIT
  Returns a flag indicating whether or not the character is a
  valid digit in the given base.  If so, returns converted
  value and true,  otherwise returns char and false.
DOUBLE?   Returns non-zero if period was encountered.
CONVERT
   Starting with the unsigned double number ud1 and the string
   at adr1, convert the string to a number in the current base.
   Leave result and address of unconvertable digit on stack.

(NUMBER?)
   Given a string containing at least one digit, convert it
   to a number.
NUMBER?
   Convert the count delimited string at addr to a double
   number.  NUMBER? takes into account a leading minus sign,
   and stores a pointer to the last delimiter in DPL.
   The string must end with a blank.
   Leaves a true flag if successful.
(NUMBER)
   Convert the count delimited string at addr to a double
   number.  (NUMBER) takes into account a leading minus sign,
   and stores a pointer to the last period in DPL.  Note the
   string must end with a blank or an error message is issued.
NUMBER   Convert a string to a number.  Normally (NUMBER)
HOLD     Save the char for numeric output later.
<#       Start numeric conversion.
#>       Terminate numeric conversion.
SIGN     If n1 is negative insert a minus sign into the string.
#        Convert a single digit in the current base.

#S       Convert a number until it is finished.

HEX        All subsequent numeric IO will be in Hexadecimal.
DECIMAL    All subsequent numeric IO will be in Decimal.
OCTAL      All subsequent numeric IO will be in Octal.

(U.)   Convert an unsigned 16 bit number to a string.
U.     Output as an unsigned single number with trailing space.
U.R    Output as an unsigned single number right justified.

(.)    Convert a signed 16 bit number to a string.
.      Output as a signed single number with a trailing space.
.R     Output as a signed single number right justified.

(UD.)  Convert an unsigned double number to a string.
UD.    Output as an unsigned double number with a trailing space
UD.R   Output as an unsigned double number right justified.

(D.)   Convert a signed double number to a string.
D.     Output as a signed double number with a trailing space.
D.R    Output as a signed double number right justified.
DONE
   A common exit routine for SKIP and SCAN.
SKIP
   Given the address and length of a string, and a character to
   look for, run through the string while we continue to find
   the character.  Leave the address of the mismatch and the
   length of the remaining string.

SCAN
   Given the address and length of a string, and a character to
   look for, run through the string until we find
   the character.  Leave the address of the match and the
   length of the remaining string.

/STRING     Index into the string by n.  Returns addr+n and
   len-n.
PLACE       Move the characters at from to to with a preceding
   length byte of len.
(SOURCE)    Returns the string to be scanned.  This is the
   default value of the deferred word SOURCE.
SOURCE      Return a string from the current input stream.
PARSE-WORD
   Scan the input stream until char is encountered.  Skip over
   leading chars.  Update >IN pointer.
   Leaves the address and length of the enclosed string.
PARSE
   Scan the input stream until char is encountered.
   Update >IN pointer.
   Leaves the address and length of the enclosed string.

'WORD   Leaves the same address as WORD.
   In this system, 'WORD is the same as HERE.
WORD
   Parse the input stream for char and return a count delimited
   string at here.  Note there is always a blank following it.

